<script setup>
import massage from "./massage.vue";
import home from "./home.vue";
import about from "./about.vue";
import { ref, computed, defineAsyncComponent, shallowRef } from "vue";
//异步组件defineAsyncComponent
const definedCompont = defineAsyncComponent(() => import("./yibuzujian.vue"));
//这里的lists必须是普通对象，不能是响应式对象，因为其中引用了组件对象，Vue期望组件是普通的对象，而不是响应式对象，否则vue给出警告，该组件是响应式对象。这可能会导致不必要的性能开销
const list = [
  {
    name: "home",
    component: home,
  },
  {
    name: "about",
    component: about,
  },
  {
    name: "massage",
    component: massage,
  },
];
// 这里也不能用ref或reactive，否则会导致title变成响应式对象，Vue期望组件home是普通的对象，而不是响应式对象，否则vue给出警告，该组件是响应式对象。这可能会导致不必要的性能开销
const title = shallowRef(home);
//总结这里动态组件还是用官网的写法吧，这种写法限制太多，不了解原因，很难写出正确代码，正确代码须注意两点(1.lists必须是普通对象,2.title需要用shallowRef定义)
</script>

<template>
  <span
    v-for="item in list"
    :key="item"
    class="classStyle"
    :class="{ active: title === item.component }"
    @click="title = item.component"
    >{{ item.name }}-{{ title === item.component }}</span
  >
  <component :is="title"></component>
  <!-- Suspense经常和异步组件一起使用 异步组件作用是提升首屏渲染的速度，
  因为异步组件会单独打包到一个js文件里，只有在需要的时候才加载，所以vue核心代码的app.js包体积会小一些，Suspense作用提升用户体验在异步组件没加载出来时显示Loading... -->
  <Suspense>
    <template #default>
      <!-- 这个根div标签是必须的，固定写法 -->
      <div>
        <definedCompont></definedCompont>
      </div>
    </template>
    <template #fallback>
      <span>Loading...</span>
    </template>
  </Suspense>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.classStyle {
  display: inline-block;
  padding: 10px;
  margin-right: 5px;
  cursor: pointer;
}

.active {
  color: red;
}
</style>
